#include "input.h"
#include "OgreStringConverter.h"

#include "GameWidget.h"
#include "statemanager.h"

InputHandler::InputHandler(GameWidget* p_GameWidget, StateManager *p_StateManager, unsigned long hWnd)
{
	m_GameWidget = p_GameWidget;
	m_StateManager = p_StateManager;
	m_hWnd = hWnd;


	m_RequestCaptureStop = false;
	m_Capture = false;

	m_StateManager->requestStateChange(GAME_PAUSED);
}

InputHandler::~InputHandler()
{
	if (mMouse)
		m_ois->destroyInputObject(mMouse);
	if (mKeyboard)
		m_ois->destroyInputObject(mKeyboard);

	if (m_ois)
		OIS::InputManager::destroyInputSystem(m_ois);
}

void InputHandler::capture()
{
	if (m_Capture)
	{
		mMouse->capture();
		mKeyboard->capture();
	}

	if (m_RequestCaptureStop)
	{
		StopCapture();
	}
}

void  InputHandler::setWindowExtents(int p_Width, int p_Height)
{
	m_Width = p_Width;
	m_Height = p_Height;
	if (m_Capture && mMouse)
	{
		//Set Mouse Region.. if window resizes, we should alter this to reflect as well
		const OIS::MouseState &ms = mMouse->getMouseState();
		ms.width = m_Width;
		ms.height = m_Height;
	}
}

// MouseListener
bool InputHandler::mouseMoved(const OIS::MouseEvent &evt)
{
	return true;
}

bool InputHandler::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID btn)
{
	return true;
}

bool InputHandler::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) {
	return true;
}


// KeyListener
bool InputHandler::keyPressed(const OIS::KeyEvent &evt)
{
	switch (evt.key)
	{
	case OIS::KC_UP:
		m_GameWidget->GetPlayer()->InvokeUp();
		break;
	case OIS::KC_DOWN:
		m_GameWidget->GetPlayer()->InvokeDown();
		break;
	case OIS::KC_LEFT:
		m_GameWidget->GetPlayer()->InvokeLeft();
		break;
	case OIS::KC_RIGHT:
		m_GameWidget->GetPlayer()->InvokeRight();
		break;
	default:
		break;
	}
	return true;
}

bool InputHandler::keyReleased(const OIS::KeyEvent &evt)
{
	switch (evt.key)
	{
	case OIS::KC_ESCAPE:
		m_RequestCaptureStop = true;
        m_StateManager->requestStateChange(GAME_PAUSED);
		break;
	case OIS::KC_UP:
		m_GameWidget->GetPlayer()->InvokeDown();
		break;
	case OIS::KC_DOWN:
		m_GameWidget->GetPlayer()->InvokeUp();
		break;
	case OIS::KC_LEFT:
		m_GameWidget->GetPlayer()->InvokeRight();
		break;
	case OIS::KC_RIGHT:
		m_GameWidget->GetPlayer()->InvokeLeft();
		break;
	case OIS::KC_R:
		m_StateManager->requestStateChange(RESET);
		break;
    case OIS::KC_E:
        m_GameWidget->GetObstacles()->Explode(m_GameWidget->GetPlayer());
        break;
    case OIS::KC_L:
        m_RequestCaptureStop = true;
        m_StateManager->requestStateChange(LEVELCHANGE);
        break;
	default:
		break;
	}
	return true;
}



// JoyStickListener
bool InputHandler::buttonPressed(const OIS::JoyStickEvent &evt, int index) {
	return true;
}

bool InputHandler::buttonReleased(const OIS::JoyStickEvent &evt, int index) {
	return true;
}

bool InputHandler::axisMoved(const OIS::JoyStickEvent &evt, int index) {
	return true;
}

bool InputHandler::povMoved(const OIS::JoyStickEvent &evt, int index) {
	return true;
}


void InputHandler::StartCapture()
{
	OIS::ParamList paramList;
	paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(m_hWnd)));

#if defined OIS_WIN32_PLATFORM
	paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
	paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
	paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
	paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
#elif defined OIS_LINUX_PLATFORM
	paramList.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("true")));
	paramList.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("true")));
	paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
	paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
#endif


	m_ois = OIS::InputManager::createInputSystem( paramList );

	mMouse = static_cast<OIS::Mouse*>(m_ois->createInputObject( OIS::OISMouse, true ));
	mKeyboard = static_cast<OIS::Keyboard*>(m_ois->createInputObject( OIS::OISKeyboard, true));
	mMouse->setEventCallback(this);
	mKeyboard->setEventCallback(this);

	//Set Mouse Region.. if window resizes, we should alter this to reflect as well
	const OIS::MouseState &ms = mMouse->getMouseState();
	ms.width = m_Width;
	ms.height = m_Height;


	m_Capture = true;
	m_StateManager->requestStateChange(GAME);
}

void InputHandler::StopCapture()
{
	if (mMouse)
	{
		m_ois->destroyInputObject(mMouse);
		mMouse = NULL;
	}
	if (mKeyboard)
	{
		m_ois->destroyInputObject(mKeyboard);
		mKeyboard = NULL;
	}

	OIS::InputManager::destroyInputSystem(m_ois);
	m_ois = NULL;
	m_Capture = false;
    m_RequestCaptureStop = false;
}
